<!DOCTYPE html>
<html lang="en">
    <head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="format-detection" content="telephone=no" />

  <title>
    39|案例篇：怎么缓解 DDoS 攻击带来的性能下降问题？ | 迪克猪的博客
  </title>

  
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
  <link rel="manifest" href="/manifest.json" />
  <meta name="theme-color" content="#ffffff" />

  
  <link
    rel="stylesheet"
    href="https://unpkg.com/modern-normalize@0.6.0/modern-normalize.css"
  />

  
  
  
  
  <link rel="stylesheet" href="https://zsy619.github.io/style.min.f7761d111b74dd5c07f0111decee92938c12abc42e0fd319e1a07483e248b54e.css" integrity="sha256-93YdERt03VwH8BEd7O6Sk4wSq8QuD9MZ4aB0g&#43;JItU4=" />

  
  
    
  
</head>

    <body>
        <header id="header">
  <div class="header_container">
    <h1 class="sitetitle">
      <a href="https://zsy619.github.io" title="迪克猪的博客">迪克猪的博客</a>
    </h1>
    <nav class="navbar">
      <ul>
        <li><a href="https://zsy619.github.io">Home</a></li>
        
          <li>
            <a href="/post/">
              
              <span>LINUX性能优化</span>
            </a>
          </li>
        
          <li>
            <a href="/csapp/">
              
              <span>深入理解计算机系统_第三版</span>
            </a>
          </li>
        
          <li>
            <a href="/golang/">
              
              <span>golang</span>
            </a>
          </li>
        
          <li>
            <a href="/docker/">
              
              <span>容器</span>
            </a>
          </li>
        
          <li>
            <a href="/flutter/">
              
              <span>Flutter</span>
            </a>
          </li>
        
          <li>
            <a href="/know/">
              
              <span>知识点</span>
            </a>
          </li>
        
          <li>
            <a href="/categories/">
              
              <span>目录</span>
            </a>
          </li>
        
          <li>
            <a href="/about/">
              
              <span>关于</span>
            </a>
          </li>
        
        <li class="hide-sm"><a href="https://zsy619.github.io/index.xml" type="application/rss+xml">RSS</a></li>
      </ul>
    </nav>
  </div>
</header>

        
<section id="main">
  <article class="post content">
    <h2 class="title">39|案例篇：怎么缓解 DDoS 攻击带来的性能下降问题？</h2>
    <div class="post_content">
      <h3 id="ddos-简介">DDoS 简介</h3>
<p>DDoS 的前身是 DoS（Denail of Service），即拒绝服务攻击，指利用大量的合理请求，来占用过多的目标资源，从而使目标服务无法响应正常请求。</p>
<p>DDoS（Distributed Denial of Service） 则是在 DoS 的基础上，采用了分布式架构，利用多台主机同时攻击目标主机。这样，即使目标服务部署了网络防御设备，面对大量网络请求时，还是无力应对。</p>
<p>比如，目前已知的最大流量攻击，正是去年 Github 遭受的 DDoS 攻击，其峰值流量已经达到了 1.35Tbps，PPS 更是超过了 1.2 亿（126.9 million）。</p>
<p>DDoS 可以分为下面几种类型。</p>
<ul>
<li>第一种，耗尽带宽。无论是服务器还是路由器、交换机等网络设备，带宽都有固定的上限。带宽耗尽后，就会发生网络拥堵，从而无法传输其他正常的网络报文。</li>
<li>第二种，耗尽操作系统的资源。网络服务的正常运行，都需要一定的系统资源，像是 CPU、内存等物理资源，以及连接表等软件资源。一旦资源耗尽，系统就不能处理其他正常的网络连接。</li>
<li>第三种，消耗应用程序的运行资源。应用程序的运行，通常还需要跟其他的资源或系统交互。如果应用程序一直忙于处理无效请求，也会导致正常请求的处理变慢，甚至得不到响应。</li>
<li>比如，构造大量不同的域名来攻击 DNS 服务器，就会导致 DNS 服务器不停执行迭代查询，并更新缓存。这会极大地消耗 DNS 服务器的资源，使 DNS 的响应变慢。</li>
</ul>
<h3 id="案例">案例</h3>
<p><img src="../../images/20200707-1606-59.png" alt=""></p>
<p>首先，在终端一中，执行下面的命令运行案例，也就是启动一个最基本的 Nginx 应用：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e"># 运行Nginx服务并对外开放80端口</span>
<span style="color:#75715e"># --network=host表示使用主机网络（这是为了方便后面排查问题）</span>
$ docker run -itd --name<span style="color:#f92672">=</span>nginx --network<span style="color:#f92672">=</span>host nginx

</code></pre></div><p>然后，在终端二和终端三中，使用 curl 访问 Nginx 监听的端口，确认 Nginx 正常启动。假设 192.168.0.30 是 Nginx 所在虚拟机的 IP 地址，那么运行 curl 命令后，你应该会看到下面这个输出界面：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e"># -w表示只输出HTTP状态码及总时间，-o表示将响应重定向到/dev/null</span>
$ curl -s -w <span style="color:#e6db74">&#39;Http code: %{http_code}\nTotal time:%{time_total}s\n&#39;</span> -o /dev/null http://192.168.0.30/
...
Http code: <span style="color:#ae81ff">200</span>
Total time:0.002s
</code></pre></div><p>从这里可以看到，正常情况下，我们访问 Nginx 只需要 2ms（0.002s）。</p>
<p>接着，在终端二中，运行 hping3 命令，来模拟 DoS 攻击：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e"># -S参数表示设置TCP协议的SYN（同步序列号），-p表示目的端口为80</span>
<span style="color:#75715e"># -i u10表示每隔10微秒发送一个网络帧</span>
$ hping3 -S -p <span style="color:#ae81ff">80</span> -i u10 192.168.0.30
</code></pre></div><p>然后，到终端三中，执行下面的命令，模拟正常客户端的连接：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e"># --connect-timeout表示连接超时时间</span>
$ curl -w <span style="color:#e6db74">&#39;Http code: %{http_code}\nTotal time:%{time_total}s\n&#39;</span> -o /dev/null --connect-timeout <span style="color:#ae81ff">10</span> http://192.168.0.30
...
Http code: <span style="color:#ae81ff">000</span>
Total time:10.001s
curl: <span style="color:#f92672">(</span>28<span style="color:#f92672">)</span> Connection timed out after <span style="color:#ae81ff">10000</span> milliseconds
</code></pre></div><p>你可以发现，在终端三中，正常客户端的连接超时了，并没有收到 Nginx 服务的响应。</p>
<p>可以回到终端一中，执行下面的命令：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">
$ sar -n DEV <span style="color:#ae81ff">1</span>
08:55:49        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
08:55:50      docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
08:55:50         eth0  22274.00    629.00   1174.64     37.78      0.00      0.00      0.00      0.02
08:55:50           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
</code></pre></div><p>在终端一中，执行下面的 tcpdump 命令：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e"># -i eth0 只抓取eth0网卡，-n不解析协议名和主机名</span>
<span style="color:#75715e"># tcp port 80表示只抓取tcp协议并且端口号为80的网络帧</span>
$ tcpdump -i eth0 -n tcp port <span style="color:#ae81ff">80</span>
09:15:48.287047 IP 192.168.0.2.27095 &gt; 192.168.0.30: Flags <span style="color:#f92672">[</span>S<span style="color:#f92672">]</span>, seq 1288268370, win 512, length <span style="color:#ae81ff">0</span>
09:15:48.287050 IP 192.168.0.2.27131 &gt; 192.168.0.30: Flags <span style="color:#f92672">[</span>S<span style="color:#f92672">]</span>, seq 2084255254, win 512, length <span style="color:#ae81ff">0</span>
09:15:48.287052 IP 192.168.0.2.27116 &gt; 192.168.0.30: Flags <span style="color:#f92672">[</span>S<span style="color:#f92672">]</span>, seq 677393791, win 512, length <span style="color:#ae81ff">0</span>
09:15:48.287055 IP 192.168.0.2.27141 &gt; 192.168.0.30: Flags <span style="color:#f92672">[</span>S<span style="color:#f92672">]</span>, seq 1276451587, win 512, length <span style="color:#ae81ff">0</span>
09:15:48.287068 IP 192.168.0.2.27154 &gt; 192.168.0.30: Flags <span style="color:#f92672">[</span>S<span style="color:#f92672">]</span>, seq 1851495339, win 512, length <span style="color:#ae81ff">0</span>
...
</code></pre></div><p><img src="../../images/20200707-1611-30.png" alt=""></p>
<p><img src="../../images/20200707-1611-52.png" alt=""></p>
<h3 id="ddos-到底该怎么防御">DDoS 到底该怎么防御</h3>
<p>当 DDoS 报文到达服务器后，Linux 提供的机制只能缓解，而无法彻底解决。即使像是 SYN Flood 这样的小包攻击，其巨大的 PPS ，也会导致 Linux 内核消耗大量资源，进而导致其他网络报文的处理缓慢。</p>
<p>对于流量型的 DDoS 来说，当服务器的带宽被耗尽后，在服务器内部处理就无能为力了。这时，只能在服务器外部的网络设备中，设法识别并阻断流量（当然前提是网络设备要能扛住流量攻击）。比如，购置专业的入侵检测和防御设备，配置流量清洗设备阻断恶意流量等。</p>
<p>DDoS 并不一定是因为大流量或者大 PPS，有时候，慢速的请求也会带来巨大的性能下降（这种情况称为慢速 DDoS）。</p>
<p>比如，很多针对应用程序的攻击，都会伪装成正常用户来请求资源。这种情况下，请求流量可能本身并不大，但响应流量却可能很大，并且应用程序内部也很可能要耗费大量资源处理。</p>
<p>这时，就需要应用程序考虑识别，并尽早拒绝掉这些恶意流量，比如合理利用缓存、增加 WAF（Web Application Firewall）、使用 CDN 等等。</p>
<h3 id="小结">小结</h3>
<p>学习了分布式拒绝服务（DDoS）时的缓解方法。DDoS 利用大量的伪造请求，使目标服务耗费大量资源，来处理这些无效请求，进而无法正常响应正常的用户请求。</p>
<p>由于 DDoS 的分布式、大流量、难追踪等特点，目前还没有方法可以完全防御 DDoS 带来的问题，只能设法缓解这个影响。</p>
<p>比如，你可以购买专业的流量清洗设备和网络防火墙，在网络入口处阻断恶意流量，只保留正常流量进入数据中心的服务器中。</p>
<p>在 Linux 服务器中，你可以通过内核调优、DPDK、XDP 等多种方法，来增大服务器的抗攻击能力，降低 DDoS 对正常服务的影响。而在应用程序中，你可以利用各级缓存、 WAF、CDN 等方式，缓解 DDoS 对应用程序的影响。</p>

    </div>
    <div class="info post_meta">
      <time datetime=2020-07-07T16:02:59&#43;0800 class="date">Tuesday, July 7, 2020</time>
      
        <ul class="tags">
        
          <li> <a href="https://zsy619.github.io/tags/linux%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96">linux性能优化</a> </li>
        
          <li> <a href="https://zsy619.github.io/tags/linux">linux</a> </li>
        
        </ul>
      
      
    </div>
    <div class="clearfix"></div>
  </article>
  
    <div class="other_posts">
      
      <a href="https://zsy619.github.io/post/38%E6%A1%88%E4%BE%8B%E7%AF%87%E6%80%8E%E4%B9%88%E4%BD%BF%E7%94%A8-tcpdump-%E5%92%8C-wireshark-%E5%88%86%E6%9E%90%E7%BD%91%E7%BB%9C%E6%B5%81%E9%87%8F/" class="prev">38|案例篇：怎么使用 tcpdump 和 Wireshark 分析网络流量？</a>
      
      
      <a href="https://zsy619.github.io/post/40%E6%A1%88%E4%BE%8B%E7%AF%87%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E5%BB%B6%E8%BF%9F%E5%8F%98%E5%A4%A7%E4%BA%86%E6%88%91%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/" class="next">40|案例篇：网络请求延迟变大了，我该怎么办？</a>
      
    </div>
    <aside id="comments">
</aside>

  
</section>

        <a id="back_to_top" title="Go To Top" href="#">
  <span>
    <svg viewBox="0 0 24 24">
      <path fill="none" d="M0 0h24v24H0z"></path>
      <path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"></path>
    </svg>
  </span>
</a>

        <footer id="footer">
  <p>
    <span>&copy; 2021 <a href="https://zsy619.github.io" title="迪克猪的博客">迪克猪的博客</a> </span>
    <span>Built with <a rel="nofollow" target="_blank" href="https://gohugo.io">Hugo</a></span>
    <span>Theme by <a rel="nofollow" target="_blank" href="https://github.com/wayjam/hugo-theme-mixedpaper">WayJam</a></span>
  </p>

  <script src="https://zsy619.github.io/js/main.min.8b182175f5874aeed0acc0979345c98d4bde22208ec4f36cc1d6e3102acb4b10.js" integrity="sha256-ixghdfWHSu7QrMCXk0XJjUveIiCOxPNswdbjECrLSxA=" crossorigin="anonymous" async></script>
</footer>

    </body>
</html>
